/*****************************************************************************************
This file is a part of Arise library.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

Arise Engine		Renderer2d.cpp

					E-mail:		arise_engine@mail.ru

					Origin by:	DK Engine 0.019,
								dev (avon.dn.ua@gmail.com), Agressor (agress0r@mail.ru);
								Haaf's Game Engine 1.5, 
								Copyright (c) 2003-2004 Relish Games
								http://hge.relishgames.com

created:			16.03.2008
last changes:		06.08.2008
*****************************************************************************************/
#include "stdafx.h"


void Renderer::RenderSprite(Sprite* sprite)
{
	if(!sprite) return;
	
	if(sprite->quad.tex != m_texture_current || sprite->quad.blend != m_blend_current)
	{
		RenderBatch2d();
		if(sprite->quad.tex != m_texture_current) m_d3d_device->SetTexture(0, sprite->quad.tex);
		if(sprite->quad.blend != m_blend_current) ApplyBlendMode(sprite->quad.blend);
		m_texture_current = sprite->quad.tex;			
	}

	memcpy(	&m_vertices2d_storage[m_num_prim2d * SPRT_NUM_VERTEX], 
			sprite->quad.v, 
			sizeof(Vertex2d) * SPRT_NUM_VERTEX	);
	m_num_prim2d++;
	m_num_render_primitives_2d++;
}


void Renderer::RenderBatch2d(bool end_scene)
{
	if(m_num_prim2d == 0) return;

	m_vertex_buffer2d->Unlock();
	m_d3d_device->DrawIndexedPrimitive(	D3DPT_TRIANGLELIST, 
										0, 
										0, 
										m_num_prim2d * SPRT_NUM_VERTEX, 
										0, 
										m_num_prim2d * 2	);
	m_num_prim2d = 0;
	m_num_dip_calls_2d++;
	//m_vertices2d_storage = 0;

	if(!end_scene) m_vertex_buffer2d->Lock(0, 0, (void**)&m_vertices2d_storage, 0);
}


bool Renderer::ReleasePool2d(UINT pool_id)
{
	if(pool_id >= m_scenes2d.size()) return false;
	m_scenes2d[pool_id].Release();

	return true;
}


void Renderer::ResetProjectionMatrix2d(int width, int height)
{
	D3DXMATRIX tmp;
	D3DXMatrixScaling(&m_ortho_projection, 1.0f, -1.0f, 1.0f);
	D3DXMatrixTranslation(&tmp, -TEXEL_TO_PIXEL_OFFSET, height+TEXEL_TO_PIXEL_OFFSET, 0.0f);
	D3DXMatrixMultiply(&m_ortho_projection, &m_ortho_projection, &tmp);
	D3DXMatrixOrthoOffCenterLH(&tmp, 0.0f, (float)width, 0.0f, (float)height, 0.0f, 1.0f);
	D3DXMatrixMultiply(&m_ortho_projection, &m_ortho_projection, &tmp);
}

void Renderer::ApplyBlendMode(int blend)
{
	if(blend & BLEND_ALPHAADD)		m_d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
	else							m_d3d_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

	if(blend & BLEND_COLORADD)		m_d3d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_ADD);			// add arguments together
	else if(blend & BLEND_COLORMUL)	m_d3d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);		// multiply args together
	else							m_d3d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);	// the default

	m_blend_current = blend;
}

